

#pragma once

#include <list>

#include "type.h"
#include "unit.h"
#include "formation.h"
#include "gamenodecontainer.h"
#include "gamemessage.h"
#include "army.h"

enum class GameState {
	start,
	playing,
	paused,
	defeat,
	win,
	end,
	draw,
};

static const char* BATTLE_STATE_NAMES[] = { "standby", "march", "melee",};

enum class BattleState {
	standby,
	march,
	melee,
};

struct UnitAssignmentData {
	int rowIndex;
	int targetRowIndex;
	int distance;

	UnitAssignmentData() {
		rowIndex = 0;
		targetRowIndex = -1;
		distance = 0;
	}
};

class Army;

class GameScene : public CCScene {
public:
	GameScene();
	virtual ~GameScene();
	CREATE_FUNC(GameScene);

	void update(float ticks);
	void setFormations(const FormationInfo* left, const FormationInfo* right);

	virtual void addOneTimeNode(ManagedGameNodeInfo info);
	virtual void addNode(CCNode *node);
	virtual void addBullet(Bullet *bullet);

public:
	bool isPausedGame;

	const FormationInfo* me;
	const FormationInfo* opponent;

	MessageTarget previousScene;

	GameState gameState;
	BattleState battleState;

private:
	virtual bool init();

	void createUI();
	void createArmies();
	void createDialogLayer();

	void handleMessage();
	void updateManagedGameNodes(float ticks);
	void updateBattlefieldTimer();

	void updateBullets(float ticks);
	void playGame(CCObject* sender);
	void pauseGame(CCObject* sender);
	void restartGame(CCObject* sender);
	void concede(CCObject* sender);
	void screenshot(CCObject* sender);

	void handleBattleStandby(float ticks);
	void handleBattleMarch(float ticks);
	void handleBattleMelee(float ticks);

	void transformBattleState(BattleState newState);

	bool isContact();
	float getContactPosition();

	void assignFrontLineMeleeTarget();
	void adjustFrontLinePositions(Army *army);
	void adjustSecondLinePositions(Army *army);
	void adjustThirdLinePositions(Army *army);

private:
	CCLayer* _bgLayer;
	CCLayer* _gameLayer;
	CCLayer* _uiLayer;

	CCLabelTTF* _labelTime;
	CCLabelTTF* _labelBattleState;

	CCMenuItemSprite* _btnResumeGame;
	CCMenuItemSprite* _btnSurrender;

	Army* myArmy;
	Army* opponentArmy;

	float _totalTicks;
	float _endlessBattleTicks;

	int _deaths;
	int _arrivals;
	int _idles;

	char buf[200];

	std::list<ManagedGameNodeInfo> _managedNodes;
	std::list<Bullet*> _bullets;

	const char* _bgTextureName;

	bool hadAssignedUnits;

public:
	virtual void visit() override;
};
